package com.xvdong.gadget;
/*
 NovelReader.java - 分页版 (支持 UTF-8 / GB2312)

改进点：
- 支持大文件分页（默认每页 5000 字符）
- 使用 RandomAccessFile 按需读取，避免一次性加载整个小说
- 每次翻页即时保存阅读进度
- 启动时恢复到上次阅读的页码
- 增加对 GB2312 编码的支持（优先 UTF-8，失败时尝试 GB2312）
- 默认目录设置为 C:\\Users\\user\\Desktop\\电子书\\book
- 左侧小说列表可关闭（折叠/隐藏）
- 翻页按钮改为 "<" ">" 并放在窗口右下角
- 新增快捷键：← → 翻页, L 显示/隐藏列表
- 修复方向键快捷键焦点问题
*/

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Properties;

import javax.swing.*;

public class NovelReader extends JFrame {
    private final DefaultListModel<File> listModel = new DefaultListModel<>();
    private final JList<File> novelList = new JList<>(listModel);
    private final JTextPane textPane = new JTextPane();
    private final JLabel statusLabel = new JLabel("欢迎来到LXD的世界");

    private final Properties progress = new Properties();
    private final Path progressFile;

    private File currentFolder = new File("C:\\Users\\user\\Desktop\\电子书\\book");
    private File currentFile = null;

    // 分页相关
    private static final int PAGE_SIZE = 10000; // 每页字符数
    private int currentPage = 0;
    private long fileLength = 0;
    private RandomAccessFile raf;

    // UI组件
    private JSplitPane split;

    public NovelReader() {
        super("DeepSeek");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(1280, 600);
        setLocationRelativeTo(null);

        Path configDir = Paths.get(System.getProperty("user.home"), ".novelreader");
        try { Files.createDirectories(configDir); } catch (IOException ignored) {}
        progressFile = configDir.resolve("progress.properties");
        loadProgress();

        initUI();
        initShortcuts();
        loadFolder(currentFolder);

        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                saveCurrentProgress();
                saveProgressFile();
            }
        });
    }

    private void initUI() {
        getContentPane().setBackground(Color.BLACK);

        novelList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        novelList.setCellRenderer(new FileListCellRenderer());
        novelList.addListSelectionListener(e -> {
            if (!e.getValueIsAdjusting()) {
                File f = novelList.getSelectedValue();
                if (f != null) openFile(f);
            }
        });

        JScrollPane listScroll = new JScrollPane(novelList);
        listScroll.setPreferredSize(new Dimension(280, 0));

        textPane.setEditable(false);
        textPane.setBackground(Color.BLACK);
        textPane.setForeground(Color.WHITE);
        textPane.setCaretColor(Color.WHITE);
        textPane.setFont(new Font("Microsoft YaHei", Font.PLAIN, 15));
        textPane.setMargin(new Insets(12, 12, 12, 12));
        JScrollPane textScroll = new JScrollPane(textPane);

        JPanel topBar = new JPanel(new FlowLayout(FlowLayout.LEFT));
        topBar.setBackground(Color.DARK_GRAY);

        JButton chooseFolderBtn = new JButton("搜索");
        JButton toggleListBtn = new JButton("折叠");

        chooseFolderBtn.addActionListener(e -> chooseFolder());
        toggleListBtn.addActionListener(e -> toggleList());

        topBar.add(chooseFolderBtn);
        topBar.add(toggleListBtn);

        statusLabel.setForeground(Color.WHITE);

        // 底部区域：状态栏 + 翻页按钮
        JPanel bottom = new JPanel(new BorderLayout());
        bottom.setBackground(Color.DARK_GRAY);
        bottom.add(statusLabel, BorderLayout.CENTER);

        JPanel navPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        navPanel.setBackground(Color.DARK_GRAY);
        JButton prevBtn = new JButton("<");
        JButton nextBtn = new JButton(">");
        prevBtn.addActionListener(e -> prevPage());
        nextBtn.addActionListener(e -> nextPage());
        navPanel.add(prevBtn);
        navPanel.add(nextBtn);

        bottom.add(navPanel, BorderLayout.EAST);

        split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, listScroll, textScroll);
        split.setDividerLocation(280);
        split.setOneTouchExpandable(true);

        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(topBar, BorderLayout.NORTH);
        getContentPane().add(split, BorderLayout.CENTER);
        getContentPane().add(bottom, BorderLayout.SOUTH);

        statusLabel.setText("加载文件夹: " + currentFolder.getAbsolutePath());
    }

    private void initShortcuts() {
        // 为 textPane 添加快捷键，保证焦点在 textPane 时也能使用
        InputMap im = textPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        ActionMap am = textPane.getActionMap();

        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "nextPage");
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "prevPage");
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_L, 0), "toggleList");

        am.put("nextPage", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                nextPage();
            }
        });
        am.put("prevPage", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                prevPage();
            }
        });
        am.put("toggleList", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) { toggleList(); }
        });
    }

    private void toggleList() {
        if (split.getLeftComponent().isVisible()) {
            split.getLeftComponent().setVisible(false);
            split.setDividerSize(0);
        } else {
            split.getLeftComponent().setVisible(true);
            split.setDividerSize(10);
            split.setDividerLocation(280);
        }
        split.resetToPreferredSizes();
    }

    private void chooseFolder() {
        JFileChooser chooser = new JFileChooser(currentFolder);
        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        chooser.putClientProperty("FileChooser.useShellFolder", Boolean.FALSE); // 避免 GUID 警告
        int r = chooser.showOpenDialog(this);
        if (r == JFileChooser.APPROVE_OPTION) {
            currentFolder = chooser.getSelectedFile();
            loadFolder(currentFolder);
            statusLabel.setText("加载文件夹: " + currentFolder.getAbsolutePath());
        }
    }

    private void loadFolder(File folder) {
        listModel.clear();
        if (!folder.exists() || !folder.isDirectory()) return;
        File[] files = folder.listFiles((dir, name) -> name.toLowerCase().endsWith(".txt"));
        if (files != null) {
            Arrays.sort(files);
            for (File f : files) listModel.addElement(f);
        }
    }

    private void openFile(File file) {
        saveCurrentProgress();
        currentFile = file;
        setTitle("DeepSeek" );

        try {
            if (raf != null) raf.close();
            raf = new RandomAccessFile(file, "r");
            fileLength = raf.length();
            currentPage = 0;

            String pos = progress.getProperty(file.getAbsolutePath());
            if (pos != null) {
                try { currentPage = Integer.parseInt(pos); } catch (NumberFormatException ignored) {}
            }
            loadPage(currentPage);
        } catch (IOException e) {
            e.printStackTrace();
            statusLabel.setText("无法读取: " + e.getMessage());
        }
    }

    private void loadPage(int page) {
        try {
            raf.seek((long) page * PAGE_SIZE);
            byte[] buf = new byte[PAGE_SIZE];
            int read = raf.read(buf);
            if (read > 0) {
                String text;
                try {
                    text = new String(buf, 0, read, StandardCharsets.UTF_8);
                } catch (Exception e) {
                    text = new String(buf, 0, read, Charset.forName("GB2312"));
                }
                if (text.length() > 0 && text.charAt(0) == '\uFEFF') {
                    text = text.substring(1);
                }
                textPane.setText(text);
                textPane.setCaretPosition(0);
                int totalPages = (int) (fileLength / PAGE_SIZE) + 1;
                statusLabel.setText("第 " + (page + 1) + " 页 / 约 " + totalPages + " 页");
                saveCurrentProgress();
                saveProgressFile();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void nextPage() {
        if ((long)(currentPage + 1) * PAGE_SIZE < fileLength) {
            currentPage++;
            loadPage(currentPage);
        }
    }

    private void prevPage() {
        if (currentPage > 0) {
            currentPage--;
            loadPage(currentPage);
        }
    }

    private void loadProgress() {
        if (Files.exists(progressFile)) {
            try (InputStream in = Files.newInputStream(progressFile)) {
                progress.load(in);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void saveProgressFile() {
        try (OutputStream out = Files.newOutputStream(progressFile)) {
            progress.store(out, "NovelReader progress (filePath -> pageNumber)");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void saveProgress(File file, int page) {
        if (file == null) return;
        progress.setProperty(file.getAbsolutePath(), Integer.toString(page));
    }

    private void saveCurrentProgress() {
        if (currentFile != null) {
            saveProgress(currentFile, currentPage);
        }
    }

    private static class FileListCellRenderer extends DefaultListCellRenderer {
        @Override
        public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);

            if (value instanceof File) {
                setText(((File) value).getName());
            }

            // 设置字体大小
            setFont(new Font("Microsoft YaHei", Font.PLAIN, 16)); // 18 可以改成你想要的字号

            // 设置背景和前景色
            setBackground(isSelected ? new Color(50, 50, 50) : Color.BLACK);
            setForeground(Color.WHITE);

            // 设置边距，相当于控制 item 高度和左右间距
            setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

            return this;
        }
    }


    public static void main(String[] args) {
        try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception ignored) {}
        SwingUtilities.invokeLater(() -> new NovelReader().setVisible(true));
    }
}